home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / GEM / EVENTHAN.D < prev    next >
Encoding:
Modula Definition  |  1990-10-09  |  14.0 KB  |  273 lines

  1. DEFINITION MODULE EventHandler;
  2.  
  3.  
  4. (*  Definitionen des 'EventHandler's der Megamax Modula-2 Biblothek
  5.  *
  6.  *  System              : Megamax Modula-2 (MOS 2.0)
  7.  *  Author & Copyright  : Manuel Chakravarty
  8.  *  Vertrieb            : Application Systems Heidelberg
  9.  *  Version             : 2.1      V#0037
  10.  *)
  11.  
  12. (*  Dieses Modul erfüllt zwei Aufgaben, ersten erleichtert es die Program-
  13.  *  mierung von Ereignisschleifen (dies ist die Sorte von Schleife, die
  14.  *  sich typischerweise um ein 'MultiEvent'-Aufruf rankt) und zweitens er-
  15.  *  laubt es das Überwachen des durch 'AESEvent' laufenden Ereignisstroms.
  16.  *
  17.  *  Die Programmierung herkömmlicher Ereignisschleifen kann man mit der
  18.  *  Prozedur 'HandleEvents' vermeiden. Statt eines Aufrufes von 'MultiEvent'
  19.  *  und den darauf folgenden IF's zum Behandlen der Ereignisse, schreibt man
  20.  *  einfach für jedes Ereignis, das man bearbeiten will ein oder mehrere Pro-
  21.  *  zeduren in ein 'ARRAY OF EventProc' und ruft danach 'HandleEvents' auf.
  22.  *  Treten nun ein oder mehrere Ereignisse auf, so werden automatisch alle
  23.  *  Prozeduren, die für eines dieser Ereignise angemeldet sind, mit den vom
  24.  *  AES gelieferten Werten aufgerufen. Diese Prozeduren müssen nach der Be-
  25.  *  arbeitung des Ereignisses mit einem BOOLEAN-Wert zurückkehren. Dabei be-
  26.  *  deutet der Wert 'TRUE', daß das Ereignis auch noch an eventuell vorhandene
  27.  *  andere Prozeduren des gleichen Typs weitergegeben werden soll. Bei der
  28.  *  Rückgabe von 'FALSE' wird das Ereignis als vollständig bearbeitet ange-
  29.  *  sehen und aus der Menge der aufgetrettenen Ereignisse gestrichen.
  30.  *  Nachdem alle Ereignisse oder Prozeduren bearbeitet sind, kehrt 'Handle
  31.  *  Events' zurück. Nun sollte man ermitteln, ob es an der Zeit ist die Er-
  32.  *  eignisschleife zu beenden, falls nicht, wird 'HandleEvents' erneut auf-
  33.  *  gerufen.
  34.  *
  35.  *  Das zweite Feature diese Moduls wird wohl seltener verwendet werden, es
  36.  *  hat aber zum Beispiel in 'TextWindows' Anwendung gefunden.
  37.  *  Es können, mit 'InstallWatchDog', für jedes Ereignis beliebig viele Über-
  38.  *  wachungsprozeduren angemeldt und diese mit 'DeInstallWatchDog' auch wie-
  39.  *  der abgemeldt werden. Wann immer nun ein Ereignis mit 'HandleEvents',
  40.  *  oder AUCH mit einer der in 'AESEvent' befindlichen Event Manager Rou-
  41.  *  tinen ermittelt wird, wird ZUERST geprüft ob für diesen Ereignistyp ein
  42.  *  "Wachhund auf der Lauer liegt". Ist dies der Fall, so wird die entspre-
  43.  *  chende Funktion aufgerufen. Falls diese nun 'TRUE' als Ergebnis liefert,
  44.  *  so wird ganz normal verfahren und das Ereignis an die aufrufende Routine
  45.  *  weitergegeben; ist der Wert aber 'FALSE', so wird das Ereignis sozusagen
  46.  *  unterschlagen und wieder das AES angesprungen, um erneut auf ein Ereignis
  47.  *  zu warten. Bei 'MultiEvent' wird das Ereignis nur aus der Menge aller
  48.  *  aufgetrettenen Ereignisse ausmaskiert und der Rest, der auch leer sein
  49.  *  kann, an die aufrufende Routine weitergegeben. Bei 'HandleEvents', wird
  50.  *  wie bei 'MultiEvent' verfahren, nur werden die Ereignisse nicht zurück-
  51.  *  gegeben, sondern die entsprechenden Prozeduren ausgeführt.
  52.  *  Bei der Benutzung von 'HandleEvents', ist folgende Besonderheit anzu-
  53.  *  merken: In der Regel werden nur solche Ereignisse vom AES erfragt, für
  54.  *  die auch Prozeduren in dem 'ARRAY OF EventProc' angegeben sind. Falls
  55.  *  aber einen Anmeldung für ein Nachrichtenereignis mittels 'InstallWatchDog'
  56.  *  vorliegt, so werden auch Nachrichtenereignise erfragt. (Wird eine Nach-
  57.  *  richt übergeben, die von keiner der angemeldeten Routine bearbeitet wer-
  58.  *  den kann, so ist Sorge getragen, daß das Ereignis nicht verloren geht)
  59.  *  Als Letztes sei noch angemerkt, daß die Aufteilung der Nachrichtenerei-
  60.  *  gnisse in die Unterpunkte nur aus Gründen der einfacheren Handhabung
  61.  *  erfolgte.
  62.  *  Dabei gilt: Meldet man eine 'MessageProc' (mit 'unspecMessage') an, so
  63.  *  wird diese bei jeder Nachricht, also sowohl bei AES-Nachrichten, als
  64.  *  auch bei Nachrichten von anderen Applikationen (in der Regel Accesory's).
  65.  *  aufgerufen. Dabei ist zu beachten, daß wann immer man mit 'AESMisc.Write
  66.  *  ToAppl' einen Nachricht absetzt, das erste Wort die Art der Nachricht,
  67.  *  das zweite Wort die Applikationsnummer des Senders und das dritte Wort
  68.  *  die Länge der Nachricht minus 16 (in Byte) enthält.
  69.  *)
  70.  
  71.  
  72. FROM SYSTEM     IMPORT WORD;
  73.  
  74. FROM GrafBase   IMPORT Point, Rectangle;
  75.  
  76. FROM GEMGlobals IMPORT GemChar, MButtonSet, SpecialKeySet;
  77.                        
  78. FROM AESEvents  IMPORT unspecMessage, menuSelected, windRedraw, windTopped,
  79.                        windClosed, windFulled, windArrowed, windHSlid,
  80.                        windVSlid, windSized, windMoved, windNewTop, accOpen,
  81.                        accClose, ArrowedMode, Event, MessageBuffer,
  82.                        RectEnterMode;
  83.  
  84.  
  85. TYPE    WatchDogCarrier = ARRAY[0..7] OF WORD;
  86.  
  87.         (*  ACHTUNG: Der Parameter 'ctrl' sollte bei watch dogs nicht
  88.          *           genutzt werden, da er nur von 'MultiEvent' und
  89.          *           nicht von 'KeyboardEvent' unterstützt wird.
  90.          *)
  91.         KeyboardProc    = PROCEDURE (VAR (* key : *) GemChar,
  92.                                      VAR (* ctrl: *) SpecialKeySet): BOOLEAN;
  93.  
  94.         MouseButtonProc = PROCEDURE ((* clicks: *) CARDINAL,
  95.                                      (* loc   : *) Point,
  96.                                      (* buts  : *) MButtonSet,
  97.                                      (* keys  : *) SpecialKeySet): BOOLEAN;
  98.  
  99.         MouseRectProc   = PROCEDURE ((* loc : *) Point,
  100.                                      (* buts: *) MButtonSet,
  101.                                      (* keys: *) SpecialKeySet): BOOLEAN;
  102.  
  103.         MessageProc     = PROCEDURE ((* buffer: *) MessageBuffer): BOOLEAN;
  104.  
  105.         TimerProc       = PROCEDURE (): BOOLEAN;
  106.  
  107.         MenuProc        = PROCEDURE ((* title: *) CARDINAL,
  108.                                      (* item : *) CARDINAL): BOOLEAN;
  109.  
  110.         WindRedrawProc  = PROCEDURE ((* handle: *) CARDINAL,
  111.                                      (* frame : *) Rectangle): BOOLEAN;
  112.                                       
  113.         WindToppedProc  = PROCEDURE ((* handle: *) CARDINAL): BOOLEAN;
  114.         
  115.         WindClosedProc  = PROCEDURE ((* handle: *) CARDINAL): BOOLEAN;
  116.         
  117.         WindFulledProc  = PROCEDURE ((*handle: *) CARDINAL): BOOLEAN;
  118.         
  119.         WindArrowedProc = PROCEDURE ((* handle: *) CARDINAL,
  120.                                      (* mode  : *) ArrowedMode): BOOLEAN;
  121.                                   
  122.         WindHSlidProc   = PROCEDURE ((* handle: *) CARDINAL,
  123.                                      (* pos   : *) CARDINAL): BOOLEAN;
  124.                                   
  125.         WindVSlidProc   = PROCEDURE ((* handle: *) CARDINAL,
  126.                                      (* pos   : *) CARDINAL): BOOLEAN;
  127.                                   
  128.         WindSizedProc   = PROCEDURE ((* handle: *) CARDINAL,
  129.                                      (* frame : *) Rectangle): BOOLEAN;
  130.                                   
  131.         WindMovedProc   = PROCEDURE ((* handle: *) CARDINAL,
  132.                                      (* frame : *) Rectangle): BOOLEAN;
  133.                                   
  134.         WindNewTopProc  = PROCEDURE ((* handle: *) CARDINAL): BOOLEAN;
  135.         
  136.         AccOpenProc     = PROCEDURE ((* id: *) CARDINAL): BOOLEAN;
  137.         
  138.         AccCloseProc    = PROCEDURE ((* id: *) CARDINAL): BOOLEAN;
  139.         
  140.         
  141.         EventProc = RECORD
  142.         
  143.                       CASE event:Event OF
  144.                       
  145.                         keyboard    : keyHdler   :KeyboardProc|
  146.                         mouseButton : butHdler   :MouseButtonProc|
  147.                         firstRect   : stRectHdler:MouseRectProc|
  148.                         secondRect  : ndRectHdler:MouseRectProc|
  149.                         message     :
  150.                                       CASE msgType:CARDINAL OF
  151.                                      
  152.                                         unspecMessage: msgHdler :MessageProc|
  153.                                         menuSelected : menuHdler:MenuProc|
  154.                                         windRedraw   : drawHdler:WindRedrawProc|
  155.                                         windTopped   : topHdler :WindToppedProc|
  156.                                         windClosed   : clsHdler :WindClosedProc|
  157.                                         windFulled   : fullHdler:WindFulledProc|
  158.                                         windArrowed  : arrwHdler:WindArrowedProc|
  159.                                         windHSlid    : hSldHdler:WindHSlidProc|
  160.                                         windVSlid    : vSldHdler:WindVSlidProc|
  161.                                         windSized    : sizeHdler:WindSizedProc|
  162.                                         windMoved    : moveHdler:WindMovedProc|
  163.                                         windNewTop   : newTHdler:WindNewTopProc|
  164.                                         accOpen      : accOHdler:AccOpenProc|
  165.                                         accClose     : accCHdler:AccCloseProc|
  166.                                         
  167.                                       END|
  168.                                       
  169.                         timer       : timeHdler :TimerProc|
  170.                         
  171.                       END;
  172.                       
  173.                     END;
  174.  
  175.  
  176. PROCEDURE InstallWatchDog (VAR handle: WatchDogCarrier; proc: EventProc);
  177.  
  178.         (*  Meldet einen watch dog, d.h. eine auf ein bestimmtes Ereignis
  179.          *  wartende Prozedur an.
  180.          *
  181.          *  Beim Aufruf wird die in 'proc' specifizierte Prozedur für
  182.          *  das ebenfalls in 'proc' angegebene Ereignis angemeldet.
  183.          *  'handle' dient einerseits zur Aufnahme einiger Informati-
  184.          *  onen für das 'EventHandler'-Modul, als auch zur Identifi-
  185.          *  kation der Prozedur beim Abmelden mit 'DeInstallWatchDog'.
  186.          *  Es ist wichtig, daß 'handle' vom Anmelden bis zum Abmelden
  187.          *  erhalten bleibt, am besten ist die Variable also global
  188.          *  zu definieren.
  189.          *  Es ist ohne Schwierigkeiten möglich ein und die selbe Pro-
  190.          *  zudur mehrmals mit VERSCHIEDENEN 'handle's anzumelden, al-
  191.          *  so zum Beispiel für 'windMoved' und 'windSized' dieselbe
  192.          *  Routine zu verwenden. Doch darf dasselbe 'handle' NIE
  193.          *  gleichzeitig für mehrere Anmeldungen herhalten!
  194.          *  Die angemeldetet Routine muß bei ihrem Aufruf, falls sie
  195.          *  Routinen aus einem GEM-Modul verwendet darauf achten, daß
  196.          *  die richtige GEM-Kennung aktiv ist!
  197.          *
  198.          *  Bei der Terminierung eines Moduls werden alle dort ange-
  199.          *  meldeten Routinen abgemeldet (Siehe 'SysInstallWatchDog')
  200.          *)
  201.          
  202. PROCEDURE SysInstallWatchDog (VAR handle: WatchDogCarrier; proc: EventProc);
  203.  
  204.         (*  Funktionsweise wie 'InstallWatchDog', nur wird keine autom.
  205.          *  Abmeldung durchgeführt.
  206.          *  Diese Routine sollte von residenten und Systemmoduln benutzt
  207.          *  werden.
  208.          *)
  209.          
  210. PROCEDURE DeInstallWatchDog (VAR handle: WatchDogCarrier);
  211.  
  212.         (*  Meldet die zu 'handle' gehörende Routine ab.
  213.          *
  214.          *  Danach kann über 'handle' wieder frei verfügt werden.
  215.          *)
  216.  
  217. PROCEDURE HandleEvents (    noClicks  : CARDINAL;
  218.                             butMask,
  219.                             butState  : MButtonSet;
  220.                             moveDirec1: RectEnterMode; rect1Size: Rectangle;
  221.                             moveDirec2: RectEnterMode; rect2Size: Rectangle;
  222.                             time      : LONGCARD;
  223.                         REF procs     : ARRAY OF EventProc;
  224.                             usedProcs : CARDINAL);
  225.  
  226.         (*  Bearbeitet eventuell anstehende Ereignisse.
  227.          *
  228.          *  Führt einen Aufruf von 'AESEvent.MultiEvent' durch, dabei werden
  229.          *  die Parameter 'noClicks' bis 'time' verwendet. Anschließend wer-
  230.          *  den für jedes aufgetrettene Ereignis die entsprechenden Routinen
  231.          *  aus 'procs' aufgerufen. Dabei wird mit dem niedrigsten Feldindex
  232.          *  begonnen und für jede Routine geprüft ab das zugehörige Ereignis
  233.          *  aufgetretten ist, falls ja, wird die Routine angesprungen. Gibt
  234.          *  die Prozedur als Ergebnis 'FALSE' zurück, so wird das Ereignis
  235.          *  aus der Menge der aufgetrettenen Ereignisse gelöscht.
  236.          *  'usedProcs' gibt an wieviele Feldelemente beachtet werden sollen.
  237.          *  Falls 'usedProcs' gleich Null ist, so werden alle Einträge behan-
  238.          *  delt.
  239.          *  Nach Abarbeitung aller Routinen kehrt 'HandleEvents' zurück.
  240.          *)
  241.          
  242. PROCEDURE ShareTime (time: LONGCARD);
  243.  
  244.         (*  Gibt Accessories oder watch dogs die Möglichkeit auf Ereignisse
  245.          *  zu reagieren.
  246.          *
  247.          *  Diese Prozedur führt einen Aufruf von 'HandleEvents' aus, der
  248.          *  dazu führt, daß nach der angegebenen Zeit 'time' (in ms) zu-
  249.          *  rückgekehrt wird.
  250.          *  Sinn und Zweck dieser Routine ist, daß eventuell im Hinter-
  251.          *  grund arbeitende Accessorys zum Zug kommen und das zweitens
  252.          *  watch dogs (s.o.) die auf message events angesetzt sind, vom
  253.          *  AES mit Nachrichten (z.B. Redraws) versorgt werden können.
  254.          *  Ein Beispiel für die Anwendung bietet 'TextWindows':
  255.          *  Benutzt ein Programm nur Fenster von 'TextWindows' und will es
  256.          *  dem Anwender die Gelegenheit zur Manipulation dieser Fenster ge-
  257.          *  ben, ohne eine Eingabeoperation durchführen zu müssen, so kann
  258.          *  es zum Beispiel regelmäßig 'ShareTime (0L)' aufrufen.
  259.          *)
  260.  
  261. PROCEDURE FlushEvents;
  262.  
  263.         (*  Holt solange Nachrichtenereignisse vom AES und verteilt Sie an
  264.          *  die angemeldeten watch dogs, bis keine mehr anstehen oder sie
  265.          *  nicht mehr angenommen werden.
  266.          *
  267.          *  Ist besser für Redraws geeignet als 'ShareTime', da oft mehrer
  268.          *  Redraw-Ereignisse anstehen, die gleich alle abgearbeitet werden
  269.          *  sollen.
  270.          *)
  271.  
  272.  
  273. END EventHandler.